package com.my.ph.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.my.ph.entity.publish.PublishHelperInfo;
import com.my.ph.entity.torrent.TorrentOption;
import com.my.ph.service.PublishHelperInfoService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class TorrentUtil {

    private static PublishHelperInfoService phiService;

    @Autowired
    public void setPhiService(PublishHelperInfoService phiService) {
        TorrentUtil.phiService = phiService;
    }

    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors() * 2,
            60,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1000),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    public static R<?> getTorrentInfo(Long id) {
        PublishHelperInfo info = phiService.getById(id);
        if (info == null) {
            return R.error("种子不存在");
        }
        if (info.getTorrentState() == 0) {
            return R.error("种子正在生成中");
        }
        if (info.getTorrentState() == 1) {
            return R.error("种子生成失败");
        }
        return R.ok(info.getTorrentPath());
    }

    public static String createTorrent(String rootPath, String torrentName, String source, Long id) {
        String torrentSavePath = UserJsonConfigUtil.getInstance().getTorrentSavePath();
        if (StrUtil.isBlank(torrentSavePath)) throw new RuntimeException("请先配置种子保存路径");
        if (!FileUtil.exist(torrentSavePath)) FileUtil.mkdir(torrentSavePath);
        Path savePath = Path.of(torrentSavePath, torrentName + ".torrent");
        PublishHelperInfo info = phiService.getById(id);

        if (info.getTorrentState() == null) {
            threadPoolExecutor.execute(() -> {
                phiService.update(new LambdaUpdateWrapper<PublishHelperInfo>().eq(PublishHelperInfo::getId, id).set(PublishHelperInfo::getTorrentName, torrentName).set(PublishHelperInfo::getTorrentState, 2));
                TorrentCreate torrentCreate = new TorrentCreate();
                try {
                    torrentCreate.create(new TorrentOption().setInputFile(new File(rootPath)).setOutputPath(savePath.toString())
                            .setAnnounceUrl(UserJsonConfigUtil.getInstance().getTorrentAnnounce()).setSource(source)
                            .setTorrentName(torrentName));
                    phiService.update(new LambdaUpdateWrapper<PublishHelperInfo>().eq(PublishHelperInfo::getId, id).set(PublishHelperInfo::getTorrentState, 2));
                } catch (Exception e) {
                    log.error("{}", e.getMessage(), e);
                    phiService.update(new LambdaUpdateWrapper<PublishHelperInfo>().eq(PublishHelperInfo::getId, id).set(PublishHelperInfo::getTorrentState, 1));
                }
            });
        }
        return savePath.toString();
    }

}
